"use strict";

module.exports = core;

// require .js/.json/.node
// .js -> 须通过module.exports/exports 导出
// .json -> JSON.parse
// any -> 别的文件按照.js解析

// 比对版本
const semver = require("semver");
// 检查用户主目录
const userHome = require("user-home");
const pathExists = require("path-exists").sync;
// 引入colors
const colors = require("colors/safe");
// 引入commander
const commander = require("commander");
// 引入dotenv
const dotenv = require("dotenv");
const path = require("path");

const pkg = require("../package.json");
const log = require("@hasaiki-cli-dev/log");
const init = require("@hasaiki-cli-dev/init");
const constants = require("./const");
// 全局定义入参args
let args;
// 实例化一个commander对象
const program = new commander.Command();

async function core() {
  try {
    checkPkgVersion();
    checkNodeVersion();
    checkRoot();
    checkUserHome();
    // checkInputArgs();
    checkEnv();
    await checkGlobalUpdate();
    registerCommand();
  } catch (error) {
    log.info(error.message);
  }
}
// 注册脚手架命令
function registerCommand() {
  program
    .name(Object.keys(pkg.bin)[0])
    .usage("<command> [options]")
    .version(pkg.version)
    .option("-d, --debug", "是否开启debug模式", false);

  // 注册命令-init
  program
    .command("init [projectName]")
    .option("-f, --force", "是否强制初始化项目")
    .action(init);

  // 开启debug模式
  program.on("option:debug", function () {
    if (program.debug) {
      process.env.LOG_LEVEL = "verbose";
    } else {
      process.env.LOG_LEVEL = "info";
    }
    log.level = process.env.LOG_LEVEL;
  });
  // 监听未命中的命令
  program.on("command:*", function (obj) {
    const availableCommands = program.commands.map((cmd) => cmd.name());
    console.log(colors.red("未知的命令 " + obj[0]));
    if (availableCommands.length > 0) {
      console.log(colors.green("可用命令 " + availableCommands.join(",")));
    }
  });
  // 解析输入的命令
  program.parse(process.argv);
  // 未输入命令 展示help
  if (program.args && program.args.length < 1) {
    program.outputHelp();
  }
}
// 检查是否为最新版本
async function checkGlobalUpdate() {
  //   1. 获取当前版本号和模块名
  const currentVersion = pkg.version;
  const npmName = pkg.name;
  //   2. 调用npm APIH获取所有版本号
  //   3. 提取所有的版本号，比对那些版本号是大于当前版本号的
  //   4. 获取最新的版本号，提示用户更新到该版本
  const { getNpmSemverVersions } = require("@hasaiki-cli-dev/get-npm-info");
  // 获取最新的版本号
  const lastVersion = await getNpmSemverVersions(currentVersion, npmName);
  if (lastVersion && semver.gt(lastVersion, currentVersion)) {
    log.warn(
      colors.yellow(`更新提示：请手动更新${npmName}，当前版本${currentVersion},最新版本${lastVersion}
                       更新命令： npm install -g ${npmName}`)
    );
  }
}

// 检查环境变量
function checkEnv() {
  const dotenv = require("dotenv");
  const dotenvPath = path.resolve(userHome, ".env");
  if (pathExists(dotenvPath)) {
    dotenv.config({
      path: dotenvPath,
    });
  }
  createDefaultConfig();
  //   log.verbose("环境变量", process.env.CLI_HOME_PATH);
}
// 创建默认配置-脚手架缓存地址
function createDefaultConfig() {
  const cliConfig = {
    home: userHome,
  };
  if (process.env.CLI_HOME) {
    cliConfig["cliHome"] = path.join(userHome, process.env.CLI_HOME);
  } else {
    cliConfig["cliHome"] = path.join(userHome, constants.DEFAULT_CLI_HOME);
  }
  process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

// 检查入参
function checkInputArgs() {
  const minimist = require("minimist");
  args = minimist(process.argv.slice(2));
  checkArgs();
}
function checkArgs() {
  if (args.debug) {
    process.env.LOG_LEVEL = "verbose";
  } else {
    process.env.LOG_LEVEL = "info";
  }
  log.level = process.env.LOG_LEVEL;
  //   log.verbose("debug", "debug.....");
}
// 检查用户主目录
function checkUserHome() {
  if (!userHome || !pathExists(userHome)) {
    throw new Error(colors.red("当前登录用户主目录不存在！"));
  }
}
// 检查root账户
function checkRoot() {
  const rootCheck = require("root-check");
  rootCheck();
  //   console.log(process.geteuid); // 获取账户id
}
// 检查node版本号
function checkNodeVersion() {
  // 第一步： 检查当前版本号
  const currentVersion = process.version;
  // 第二步： 比对最低版本号
  const lowestVersion = constants.LOWEST_NODE_VERSION;
  // 第三步： 进行比对
  if (!semver.gte(currentVersion, lowestVersion)) {
    throw new Error(
      colors.red(`hasaiki-cli 需要安装v${lowestVersion} 以上的node.js版本`)
    );
  }
}
// 检测包版本号
function checkPkgVersion() {
  log.notice("cli version", pkg.version);
}
